﻿//using System;
//using System.Collections.Generic;
//using System.Text;
//using DCRF.Common.Core;
//using DCRF.Common.Primitive;
//using DCRF.Common.Helper;
//using System.Reflection;
//using DCRF.Common.DBC;
//using DCRF.Common.Interface;
//using DCRF.Common.Collection;
//using DBML.Interface;

//namespace DCRF.BaseBlocks
//{
//    public class Security : BlockBase
//    {
//        public override BlockInfo BlockInfo
//        {
//            get
//            {
//                BlockInfo result = new BlockInfo();
//                result.BlockID = new CID("Security", new BlockVersion(1, 0, 0, 0), "DCRF");
//                return result;
//            }
//        }

//        public override BlockType Type
//        {
//            get
//            {
//                return BlockType.SingleInstance;
//            }
//        }

//        public override void InitProperties()
//        {
//            Properties.Add(PRO.UserEntityName, typeof(string));
//            Properties.Add(PRO.RoleEntityName, typeof(string));
//            Properties.Add(PRO.PermissionEntityName, typeof(string));
//            Properties.Add(PRO.ActionEntityName, typeof(string));
//            Properties.Add(PRO.UserRoleEntityName, typeof(string));

//            Properties.Add(PRO.UserNameAttribute, typeof(string));
//            Properties.Add(PRO.RoleNameAttribute, typeof(string));
//            Properties.Add(PRO.RoleDefaultGrantAttribute, typeof(string));
//            Properties.Add(PRO.ActionNameAttribute, typeof(string));
//            Properties.Add(PRO.PermissionGrantAttribute, typeof(string));
//        }

//        private bool isAuthenticated = false;
//        private object userId = null;
//        private object roleId = null;
//        private string userRole = null;
//        private string userName = null;
        
//        //cached data upon authentication
//        private bool defaultGrant = false;
//        private Dictionary<string, bool> userPermissions = new Dictionary<string, bool>();

//        public override void InitConnectors()
//        {
//            addConnector(CON.DataSourceGetRows);
//            addConnector(CON.EntitySchemaGetFK);
//            addConnector(CON.EntitySchemaGetPK);
//            addConnector(CON.DataSourceGetRow);
//        }

//        [BlockService]
//        public object GetUserId()
//        {
//            if (isAuthenticated) return userId;

//            return null;
//        }

//        [BlockService]
//        public bool AuthenticateUser(string userName, string pass, string role)
//        {
//            string dbPass = null;
//            getUserIdAndPass(userName, out dbPass, out userId);
//            List<string> roles = getUserRoles(userId);

//            if (roles.Contains(role) == false)
//            {
//                resetUserCache();
//                return false;
//            }

//            if (dbPass != pass)
//            {
//                resetUserCache();
//                return false;
//            }

//            this.userName = userName;
//            this.userRole = role;

//            this.roleId = getRoleId(role);
//            userPermissions = getPermissions(roleId);
//            defaultGrant = getDefaultGrant(roleId);
//            isAuthenticated = true;

//            return true;
//        }

//        private bool getDefaultGrant(object roleId)
//        {
//            string rolePK = processConnector<string>(CON.EntitySchemaGetPK, this[PRO.RoleEntityName]);
//            IDataRow row = processConnector<IDataRow>(CON.DataSourceGetRow, this[PRO.RoleEntityName], rolePK, roleId);

//            if (row == null) throw new Exception("Invalid role id");

//            return (bool)row.GetFieldValue(this[PRO.RoleDefaultGrantAttribute]);
//        }

//        private Dictionary<string, bool> getPermissions(object roleId)
//        {
//            string roleFKInPermission = processConnector<string>(CON.EntitySchemaGetFK, this[PRO.RoleEntityName],
//                this[PRO.PermissionEntityName]);

//            IRowCollection rows = processConnector<IRowCollection>(CON.DataSourceGetRows, this[PRO.PermissionEntityName],
//                roleFKInPermission, roleId);

//            if (rows == null) return new Dictionary<string, bool>();

//            Dictionary<object, bool> result = new Dictionary<object, bool>();
//            string actionFKInPermission = processConnector<string>(CON.EntitySchemaGetFK, this[PRO.ActionEntityName],
//                this[PRO.PermissionEntityName]);

//            for (int i = 0; i < rows.Count; i++)
//            {
//                IDataRow row = rows.GetItem(i) as IDataRow;

//                object actionId = null;
//                bool isGrant = false;

//                isGrant = (bool) row.GetFieldValue(this[PRO.PermissionGrantAttribute]);
//                actionId = row.GetFieldValue(actionFKInPermission);

//                result.Add(actionId, isGrant);
//            }

//            Dictionary<string, bool> finalResult = new Dictionary<string,bool>();

//            //now convert actionIds to actionNames
//            foreach(object key in result.Keys)
//            {
//                string actionName = getActionName(key);

//                finalResult.Add(actionName, result[key]);
//            }

//            return finalResult;
//        }

//        private string getActionName(object actionId)
//        {
//            string actionPK = processConnector<string>(CON.EntitySchemaGetPK, this[PRO.ActionEntityName]);
//            IDataRow row = processConnector<IDataRow>(CON.DataSourceGetRow, this[PRO.ActionEntityName],
//                actionPK, actionId);

//            if (row == null) return null;

//            return row.GetFieldValue(this[PRO.ActionNameAttribute]).ToString();
//        }

//        private object getRoleId(string role)
//        {
//            IDataRow row = processConnector<IDataRow>(CON.DataSourceGetRow, this[PRO.RoleEntityName], this[PRO.RoleNameAttribute], role);

//            if (row == null) return null;

//            string rolePK = processConnector<string>(CON.EntitySchemaGetPK, this[PRO.RoleEntityName]);

//            return row.GetFieldValue(rolePK);
//        }

        
//        private List<string> getUserRoles(object userId)
//        {
//            //get a list of roleIDs that the user has
//            string userRoleFKForUser = processConnector<string>(CON.EntitySchemaGetFK, this[PRO.UserEntityName],
//                this[PRO.UserRoleEntityName]);

//            IRowCollection userRoleRows = processConnector<IRowCollection>(CON.DataSourceGetRows, this[PRO.UserRoleEntityName],
//                userRoleFKForUser, userId);

//            List<string> result = new List<string>();

//            if (userRoleRows == null) return result;

//            for (int i = 0; i < userRoleRows.Count; i++)
//            {
//                IDataRow row = userRoleRows.GetItem(i) as IDataRow;

//                result.Add(row.GetFieldValue(this[PRO.RoleNameAttribute]).ToString());
//            }

//            return result;
//        }

//        private void getUserIdAndPass(string userName,out string pass,out object id)
//        {
//            IDataRow userRow = Connectors[CON.DataSourceGetRow].ProcessRequest<IDataRow>(this[PRO.UserEntityName],
//                this[PRO.UserNameAttribute], userName);

//            if (userRow == null)
//            {
//                pass = null;
//                id = null;

//                return;
//            }

//            string userPKField = Connectors[CON.EntitySchemaGetPK].ProcessRequest<string>(this[PRO.UserEntityName]);
//            id = userRow.GetFieldValue(userPKField);
//            pass = userRow.GetFieldValue(this[PRO.UserNameAttribute]).ToString();
//        }

//        private void resetUserCache()
//        {
//            isAuthenticated = false;
//            userPermissions.Clear();
//            userName = null;
//            userRole = null;
//            userId = null;
//        }

//        [BlockService]
//        public bool HasPermission(string action)
//        {
//            if (userPermissions.ContainsKey(action)) return userPermissions[action];

//            return defaultGrant;
//        }

//        //private void initUserCache()
//        //{
//        //    string actionPKAttribute = processConnector<string>(CON.EntitySchemaGetPK, this[PRO.ActionEntityName]);

//        //    string permissionFKRoleAttribute = processConnector<string>(CON.EntitySchemaGetFK, this[PRO.RoleEntityName],
//        //                        this[PRO.PermissionEntityName]);

//        //    string permissionFKActionAttribute = processConnector<string>(CON.EntitySchemaGetFK, this[PRO.ActionEntityName],
//        //                        this[PRO.PermissionEntityName]);

//        //    object actionId = getRowId(this[PRO.ActionEntityName], this[PRO.ActionNameAttribute],
//        //                        action, actionPKAttribute);

//        //    IRowCollection rows = processConnector<IRowCollection>(CON.DataSourceGetRows,
//        //        this[PRO.PermissionEntityName],
//        //        permissionFKRoleAttribute, userRoleId.ToString(),
//        //        permissionFKActionAttribute, actionId.ToString());

//        //    if (rows.Count == 1)
//        //    {
//        //        IValueObject row = rows.GetItem(0) as IValueObject;

//        //        object grant = row.GetFieldValue(this[PRO.PermissionGrantAttribute]);

//        //        return (bool)grant;
//        //    }

//        //    if (rows.Count == 0)
//        //    {
//        //        string userRoleFKAttribute = processConnector<string>(CON.EntitySchemaGetFK, this[PRO.RoleEntityName], this[PRO.UserRoleEntityName]);
//        //        string userRolePK = processConnector<string>(CON.EntitySchemaGetPK, this[PRO.UserRoleEntityName]);

//        //        //get roleId by using userRoleId
//        //        IValueObject userRoleRow = getRow(this[PRO.UserRoleEntityName],
//        //                                userRolePK, userRoleId.ToString());

//        //        object roleId = userRoleRow.GetFieldValue(userRoleFKAttribute);

//        //        //now get default grant for this role
//        //        IValueObject roleRow = getRow(this[PRO.RoleEntityName],
//        //                                userRolePK,
//        //                                roleId.ToString());

//        //        return (bool)roleRow.GetFieldValue(this[PRO.RoleDefaultGrantAttribute]);
//        //    }

//        //    return false;
//        //}

//        private object getRowId(string entityName, string fieldName, string fieldValue,string pkFieldName)
//        {
//            //get user entity
//            IRowCollection rows = Connectors[CON.DataSourceGetRows].ProcessRequest<IRowCollection>(entityName,
//                fieldName, fieldValue);

//            if (rows.Count != 1) throw new Exception("Invalid id");

//            IDataRow userRow = rows.GetItem(0) as IDataRow;

//            return userRow.GetFieldValue(pkFieldName);
//        }

//        private IDataRow getRow(string entityName, string pkField, string value)
//        {
//            IRowCollection rows = Connectors[CON.DataSourceGetRows].ProcessRequest<IRowCollection>(entityName,
//                    pkField, value);

//            if (rows.Count == 1) return rows.GetItem(0) as IDataRow;

//            return null;
//        }

//        #region metadata

//        public class PRO
//        {
//            public const string RoleEntityName = "RoleEntityName";
//            public const string UserEntityName = "UserEntityName";
//            public const string PermissionEntityName = "PermissionEntityName";
//            public const string ActionEntityName = "ActionEntityName";
//            public const string UserRoleEntityName = "UserRoleEntityName";

//            public const string UserNameAttribute = "UserNameAttribute";
//            public const string RoleNameAttribute = "RoleNameAttribute";
//            public const string RoleDefaultGrantAttribute = "RoleDefaultGrantAttribute";
//            public const string ActionNameAttribute = "ActionNameAttribute";
//            public const string PermissionGrantAttribute = "PermissionGrantAttribute";
//        }

//        protected class CON
//        {
//            public const string DataSourceGetRows = "DataSourceGetRows";
//            public const string DataSourceGetRow = "DataSourceGetRow";
//            public const string EntitySchemaGetPK = "EntitySchemaGetPK";
//            public const string EntitySchemaGetFK = "EntitySchemaGetFK";
//        }

//        #endregion

//    }
//}
